/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.djdb.game.othello;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JPanel;


/**
* @author Lieven Roegiers
* @copyright 2012
* @from JAVA_othello
* @repos http://code.google.com/p/java-hogeschool-projecten/
*/
public class Bord extends JPanel implements IBord{
	private int size = 60;//moet deelbaar zijn door 3
    public Color mazecolor =Color.black;
    public Color dotcolor = Color.black;
    private Steen velden[][];
    private char bordchars[]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',};
    private Zet zetten[];
    protected boolean iskleuraanbeurt= true;
    private int rijen;//Y
    private int kolommen;//X
    private boolean isGeldig;
    private Steen steen;
    private Font small = new Font("Arial", Font.BOLD, 14);
    private MouseListener listener =  new MouseAdapter(){
        public void mouseClicked(MouseEvent m){
        	Itouch(m.getX(),m.getY());
        		//selectedComponent=getComponentAt(m.getX(),m.getY());
              	//System.out.println(selectedComponent.getName());
                }
           };
      
    Bord() throws OutOfBoundException{
        this(8,8,45);
    }
    Bord(int rijen, int kolommen ,int blocksize) throws OutOfBoundException{
        this.rijen=rijen;
        this.kolommen=kolommen;
        this.size = blocksize;
        if(rijen<3||kolommen<3){
        	throw new OutOfBoundException();
        }
        this.init();
        addMouseListener(listener );
        zetten = new Zet[rijen*kolommen];
    }
    private void clearallfields(){
    	for (int x = 0; x<this.rijen;x++) {
    		for (int y = 0; y<this.kolommen;y++){
    			velden[x][y]=null;
    		}
    	}
    }
    public void Itouch(int x,int y){
    	int rij= (y/size)-1;
    	int kolom = (x/size)-1;
    	if(rij>=0&&kolom>=0&& kolom<kolommen && rij<rijen){
    		log(Level.SEVERE,"Itouch rij"+(rij)+" kolom"+(kolom));
    		if(isgeldigezet(rij, kolom, iskleuraanbeurt)){
    			System.out.println("geldige zet");
    			Zet(rij, kolom);
    		}else{
    			System.out.println("geen geldige zet");
    		}
    	}else if(rij==0 && kolom == kolommen){
    		System.out.println("er werd gepassed");
        	iskleuraanbeurt =!iskleuraanbeurt;
        	repaint();
    	}
    }
    void reset(int rijen, int kolommen ){
    	clearallfields();
    	this.rijen = rijen;
    	this.kolommen = kolommen;
    	init();
    }
    private void init(){
        setBackground(new Color(0, 80,00));//#008000
    	velden = new Steen[rijen][kolommen];
    	int links = 0;
    	int top  = 0;
    	if (this.rijen %2<1){
    		top = this.rijen /2;
    	}else {
    		top = this.rijen-1 /2;
    	}
    	if (this.kolommen %2<1){
    		links = this.kolommen /2;
    	}else{
    		links = this.kolommen-1 /2;
    	}
    	this.velden[links-1][top-1] = new Steen(false);
    	this.velden[links][top-1] = new Steen(true);
    	this.velden[links-1][top] = new Steen(true);
    	this.velden[links][top] = new Steen(false);
    	repaint();
    }
    public static  boolean isGeldigeGrootte(int rijen,int kolommen){
        return true;
    }
    public void Zet(int rij,int kolom){
    	this.velden[rij][kolom] = new Steen(iskleuraanbeurt);
    	checkdraaien(rij,kolom,-1,0);
    	checkdraaien(rij,kolom,0,-1);
    	checkdraaien(rij,kolom,1,0);
    	checkdraaien(rij,kolom,0,1);
    	checkdraaien(rij,kolom,1,1);
    	checkdraaien(rij,kolom,-1,-1);
    	checkdraaien(rij,kolom,1,-1);
    	checkdraaien(rij,kolom,-1,1);
    	iskleuraanbeurt =!iskleuraanbeurt;
    	//Logger.getLogger(Bord.class.getName()).log(Level.SEVERE, toString());
    	repaint();
    }
    private boolean checkdraaien(int rij,int kolom,int rijplus,int kolomplus ){
    	log( Level.SEVERE,"checkdraaien?:rij"+rij+" kolom"+kolom);
    	boolean gekleurd = iskleuraanbeurt;
    	int dx = rij+rijplus;
    	int dy = kolom+kolomplus;
    	if(dx>=0 && dy>=0 && dx<kolommen && dy<rijen&&!isempty(dx, dy)){
        	log( Level.SEVERE,"checkdraaienb?:rij"+dx+" kolom"+dy);
            if(isTegenstander(dx,dy,gekleurd)){
            	 if(checkdraaien(dx,dy,rijplus,kolomplus)){
            		 draai(dx,dy);
            		 return true;
            	 }else{
            		 return false;
            	 }     
            }else if(this.velden[dx][dy]!=null&&this.velden[dx][dy].gekleurd==gekleurd){
            	 return true;
            }
        }
    	return false;
    }
    private void draai(int rij,int kolom){
    	this.velden[rij][kolom].switchstone();
    }
    public Steen getveld(int rij ,int kolom){
        return steen;
    }
    public void startgame(){
        velden = new Steen[this.rijen][this.kolommen];
    }
    public boolean isempty(int x,int y){
    	try{
    		Steen s =this.velden[x][y];
    		//syso	s.toString();
    		return  s==null&& s.isgekleurd();
    	}catch(NullPointerException e){
    		return true;
    	}
    }
    /**
     * X,Y heeft de huidige positie van het te zetten steen
     * @param 
     * @param gekleurd geeft weer of een steen is gekleurd
     */
    public boolean isaanliggend(int x,int y,boolean gekleurd){
        boolean sluitin = false;
        int xupper = x;
        int yupper = y;
        ++xupper;
        ++yupper;
        int xlower = x;
        int ylower = y;
        --xlower;
        --ylower;
        if(x<0 || y<0 || x>kolommen ||y>rijen){
        	System.out.println("null or out of range");
        	return false;
        }
        //log(Level.SEVERE,"isaanliggend:rij"+xupper+" kolom"+yupper);
        if(xlower>0 && isTegenstander(xlower,y ,gekleurd)){//boven is een ander kleur
        	System.out.println("combinatie 1");
            if (sluitIn(x, y, -1, 0, gekleurd)){
            	sluitin = true;
            }
        }
        if(ylower>0 && isTegenstander(x,ylower,gekleurd)){//links is een andere kleur
        	System.out.println("combinatie 2");
        	if (sluitIn(x, y, 0, -1, gekleurd)){
            	sluitin = true;
            } 
        }
        if(xupper<kolommen && isTegenstander(xupper,y ,gekleurd)){//onder is een ander kleur
        	System.out.println("combinatie 3");
        	if (sluitIn(x, y, 1, 0, gekleurd)){
            	sluitin = true;
            } 
        }
        if(yupper<rijen && isTegenstander(x,yupper ,gekleurd)){//rechts is een ander kleur
        	System.out.println("combinatie 4");
        	if (sluitIn(x, y, 0, 1, gekleurd)){
            	sluitin = true;
            } 
        }
        if(xlower>0 && ylower>0&& isTegenstander(xlower,ylower ,gekleurd)){//links boven is een andere kleur
        	System.out.println("combinatie 5");
        	if (sluitIn(x, y, -1, -1, gekleurd)){
            	sluitin = true;
            }
        }
        if(xupper<kolommen && yupper<rijen && isTegenstander(xupper,yupper ,gekleurd)){//rechts onder is een ander kleur
        	System.out.println("combinatie 6");
        	if (sluitIn(x, y, 1, 1, gekleurd)){
            	sluitin = true;
            }
        }
        if(xlower>0 && yupper<rijen && this.velden[xlower][yupper]!=null&&this.velden[xlower][yupper].gekleurd!=gekleurd){//rechts boven is een andere kleur
        	System.out.println("combinatie 7");
        	if (sluitIn(x, y, -1, 1, gekleurd)){
            	sluitin = true;
            }
        }
        if(ylower>0 && xupper<kolommen && this.velden[xupper][ylower]!=null&&this.velden[xupper][ylower].gekleurd!=gekleurd){//links onder is een ander kleur
        	System.out.println("combinatie 8");
        	if (sluitIn(x, y, 1, -1, gekleurd)){
            	sluitin = true;
            } 
        }
        return sluitin;
    }
    /**
     * kijkt of het een geldige zet is op de aangegeven x,y positie
     */
    public boolean isgeldigezet(int x,int y,boolean gekleurd){
        return isempty(x, y)&& isaanliggend(x,y,gekleurd);
    }
    public boolean undo(){
    	return false;
    }
    public boolean sluitIn(int x,int y,int Xplus, int Yplus,boolean gekleurd){
    	log( Level.SEVERE,"sluitina?:rij"+x+" kolom"+y);
    	if(isempty(x, y)){
    		log( Level.SEVERE,"sluitIn:leeg x"+x+"y"+y);
    		
    	}else{
    		if(this.velden[x][y].gekleurd==gekleurd){
    			log( Level.SEVERE,"gekleurd");
    		}else{
    			log( Level.SEVERE,"Wit");
    		}
    	}
    	int dx = x+Xplus;
    	int dy = y+Yplus;
    	if(dx<0 || dy<0 || dx>=rijen ||dy>=kolommen){//this is recursieve controle out of range
            return false;//out of range
        }else{
        	log( Level.SEVERE,"sluitinb?:rij"+dx+" kolom"+dy);
            if(isTegenstander(dx,dy,gekleurd)){
                 return sluitIn(dx,dy,Xplus,Yplus,gekleurd);      
            }else if(this.velden[dx][dy]!=null&&this.velden[dx][dy].gekleurd==gekleurd){
            	log( Level.SEVERE,"OK");
                return true;
            }
        }
    	log( Level.SEVERE,"NOK");
        return false;
    }
    private boolean isTegenstander(int x,int y ,boolean gekleurd){
        return this.velden[x][y]!=null&&this.velden[x][y].gekleurd!=gekleurd;
    }
    @Override
    public String toString() {
    	StringBuilder builder = new StringBuilder();
    	for (int x = 0; x<this.rijen;x++) {
    		for (int y = 0; y<this.kolommen;y++){
        		try{
        			if(this.velden[x][y]!=null){
        			      builder.append(this.velden[x][y]);
        			}else{
        				builder.append(" x"+x+"y"+y+" ");
        			}
        		}catch(NullPointerException e){
        			builder.append("NULL x"+x+"y"+y+" ");
        		}
    		}
    		builder.append("\n");
    	}
    	return new String(builder);
    }
    public void DrawMaze(Graphics2D g) {
        short i = 0;
        int x, y,dx,dy;
        int p =size-10;
        log( Level.SEVERE,rijen*size+"y"+kolommen*size+"size");
        for (x = rijen; x >0 ; --x) {
        	g.setColor(Color.white);
        	g.setFont(small);
            g.drawString(new Integer(x).toString(), size-14, x*size+(size/2));
            for (y = kolommen; y >0 ; --y) {
            	if(x==1){
            		g.setColor(Color.white);
            		g.drawChars(bordchars, y-1, 1,y*size+(size/2), size-14);
            	}
                g.setColor(mazecolor);
                g.setStroke(new BasicStroke(2));
                 dx = x*size;
                 dy = y*size;
            	g.drawLine(dx, dy, dx, dy + size - 1);
                g.drawLine(dx, dy, dx + size - 1, dy);
                g.drawLine(dx + size - 1, dy, dx + size - 1,dy + size - 1);
                g.drawLine(dx, dy + size - 1, dx + size - 1,dy + size - 1);
	                if (!isempty(x-1, y-1)){ // draws point
	                   if(this.velden[x-1][y-1].gekleurd ==false){
	                	   g.setColor(Color.white);
	                   }else{
	                	   g.setColor(dotcolor);
	                   }
	                   g.fillOval( dy+5,dx+5, p, p);
	                }
                i++;
            }
        }
    }
    public void paint(Graphics g){
    	super.paint(g);
    	Graphics2D g2d = (Graphics2D)g;
    	paintIt(g2d);
        String s2 = "PLEASE BE ALLERT UNDERCONSTRUCTION NOT WORKING EDITION.CAN HAVE BUGS?";
        FontMetrics metr = this.getFontMetrics(small);
        g2d.setColor(Color.white);
        g2d.setFont(small);
        g2d.drawString(s2, 28, 14);
    }
    private void log(Level level, String msg) {
	    String tag ="<>>>>*---------------othelo--------------*<<<<>";
	    Logger.getLogger(Bord.class.getName()).log(level, tag + msg);
	}
    private void paintIt(Graphics2D g){
    	log( Level.SEVERE,"paint=>\n"+toString());
        DrawMaze(g);
    }
	public void paintComponent(Graphics g) {
	    super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(new Color(0, 32, 48));
    	//if(Statics.FOLLOW){	log(Level.ALL,"paint");}
    	DrawMaze(g2d);
    	if(iskleuraanbeurt ==false){
     	   g.setColor(Color.white);
        }else{
     	   g.setColor(dotcolor);
        }
        g.fillOval( kolommen*size+5+size,1*size, size-10, size-10);
    	if(iskleuraanbeurt ==true){
      	   g.setColor(Color.white);
         }else{
      	   g.setColor(dotcolor);
         }
        String s2 = "Pass";
        g2d.setFont(new Font("Arial", Font.BOLD, 10));
        g2d.drawString(s2, kolommen*size+10+size, 1*size+18);
	}
}
